import json
import os
from PIL import Image
from pathlib import Path

card_data_path = 'src/main/resources/bocchi/data/card/'
power_data_path = 'src/main/resources/bocchi/data/power/'
card_localization_path = 'src/main/resources/bocchi/localization/zhs/card.json'
power_localization_path = 'src/main/resources/bocchi/localization/zhs/power.json'

raw_folder = 'raw/'
mask_folder = 'mask/'
output_folder = 'src/main/resources/bocchi/image/card/'


def process_image(input_path: str, mask_path: str, output_path: str) -> None:
    raw_image = Image.open(input_path)
    mask = Image.open(mask_path)
    masked_image = raw_image.resize(mask.size)
    masked_image.putalpha(mask.convert('L'))
    masked_image.save(output_path)


def process_images(data: dict[str, dict[str, object]]) -> None:
    for card_id, card in data.items():
        card_name = card['NAME']
        card_type = str(card['TYPE']).lower()
        raw_image_path = os.path.join(raw_folder, f'{card_name}.png')
        mask_image_path = os.path.join(mask_folder, f'{card_type}.png')
        mask_small_image_path = os.path.join(mask_folder, f'{card_type}_small.png')
        image_output_path = os.path.join(output_folder, f'{card_id}_p.png')
        image_small_output_path = os.path.join(output_folder, f'{card_id}.png')

        if (not os.path.exists(raw_image_path)
                or not os.path.exists(mask_image_path)
                or not os.path.exists(mask_small_image_path)
                or os.path.exists(image_output_path)
                or os.path.exists(image_small_output_path)):
            continue

        process_image(raw_image_path, mask_image_path, image_output_path)
        process_image(raw_image_path, mask_small_image_path, image_small_output_path)


def process_default() -> None:
    raw_image_path = os.path.join(raw_folder, '默认.png')
    card_types = ['attack', 'skill', 'power', 'status', 'curse']

    for card_type in card_types:
        mask_image_path = os.path.join(mask_folder, f'{card_type}.png')
        mask_small_image_path = os.path.join(mask_folder, f'{card_type}_small.png')
        image_output_path = os.path.join(output_folder, f'default/{card_type}_p.png')
        image_small_output_path = os.path.join(output_folder, f'default/{card_type}.png')

        process_image(raw_image_path, mask_image_path, image_output_path)
        process_image(raw_image_path, mask_small_image_path, image_small_output_path)


def sort_data(data: dict[str, dict[str, object]]):
    rarity_value = {
        'BASIC': 0,
        'COMMON': 1,
        'UNCOMMON': 2,
        'RARE': 3,
        'SPECIAL': 4,
        'CURSE': 5,
    }

    type_value = {
        'ATTACK': 0,
        'SKILL': 0.1,
        'POWER': 0.2,
        'STATUS': 0.3,
        'CURSE': 0.4,
    }

    sorted_data = sorted(data.items(), key=lambda item: rarity_value[item[1]['RARITY']] + type_value[item[1]['TYPE']])
    data.clear()
    data.update(dict(sorted_data))


def count_data(data: dict[str, dict[str, object]]):
    print(f'cards count: {len(data)}')

    def count_up(dic, key):
        if key not in dic:
            dic[key] = 0
        dic[key] += 1

    counts = {}
    for card in data.values():
        count_up(counts, card['TYPE'])
        count_up(counts, card['RARITY'])

        if 'TAGS' not in card:
            continue

        for tag in card['TAGS']:
            count_up(counts, tag)

    for key, value in counts.items():
        print(f'{key} count: {value}')


def data_to_localization(data: dict[str, dict[str, object]]) -> dict[str, dict[str, object]]:
    result = {}
    for key, value in data.items():
        local = {'NAME': value['NAME'], 'DESCRIPTION': value['DESCRIPTION']}
        if 'UPGRADE_DESCRIPTION' in value:
            local['UPGRADE_DESCRIPTION'] = value['UPGRADE_DESCRIPTION']

        if 'FLAVOR' in value:
            local['FLAVOR'] = value['FLAVOR']

        key = 'bocchi:' + key
        result[key] = local

    return result


def data_to_power_localization(data: dict[str, dict[str, object]]) -> dict[str, dict[str, object]]:
    result = {}
    for key, value in data.items():
        if 'POWER_DESCRIPTIONS' not in value:
            continue
        local = {'NAME': value['NAME'], 'DESCRIPTIONS': value['POWER_DESCRIPTIONS']}
        key = 'bocchi:' + key
        result[key] = local
    return result


if __name__ == '__main__':
    process_default()
    card_localization = {}
    power_localization = {}

    for path in Path(power_data_path).glob('*.json'):
        with open(path, 'r', encoding='utf-8') as f:
            power_localization.update(json.load(f))

    for path in Path(card_data_path).glob('*.json'):
        with open(path, 'r', encoding='utf-8') as f:
            card_data = json.load(f)

        sort_data(card_data)
        with open(path, 'w', encoding='utf-8') as f:
            json.dump(card_data, f, indent=2, ensure_ascii=False)

        process_images(card_data)

        card_localization.update(data_to_localization(card_data))
        power_localization.update(data_to_power_localization(card_data))

    with open(card_localization_path, 'w', encoding='utf-8') as f:
        json.dump(card_localization, f, indent=2, ensure_ascii=False)

    with open(power_localization_path, 'w', encoding='utf-8') as f:
        json.dump(power_localization, f, indent=2, ensure_ascii=False)
